﻿using System.Text;

namespace XUCrypto
{
    public class XUCryptoRC4
    {
        static public byte[] Encrypt(byte[] data, string password)
        {
            if (data == null || password == null)
            {
                return null;
            }

            long i = 0;
            long j = 0;
            byte[] mBox = GetKey(Encoding.Default.GetBytes(password), 256);
            byte[] output = new byte[data.Length];
            for (long offset = 0; offset < data.Length; offset++)
            {
                i = (i + 1) % mBox.Length;
                j = (j + mBox[i]) % mBox.Length;
                byte temp = mBox[i];
                mBox[i] = mBox[j];
                mBox[j] = temp;
                byte a = data[offset];
                byte b = mBox[(mBox[i] + mBox[j]) % mBox.Length];
                output[offset] = (byte)(a ^ b);
            }
            return output;
        }

        static public byte[] Decrypt(byte[] data, string pass)
        {
            return Encrypt(data, pass);
        }

        /// <summary>
        /// 打乱密码
        /// </summary>
        /// <param name="pass">密码</param>
        /// <param name="kLen">密码箱长度</param>
        /// <returns>打乱后的密码</returns>
        static private byte[] GetKey(byte[] pass, int kLen)
        {
            byte[] mBox = new byte[kLen];
            for (long i = 0; i < kLen; i++)
            {
                mBox[i] = (byte)i;
            }
            long j = 0;
            for (long i = 0; i < kLen; i++)
            {
                j = (j + mBox[i] + pass[i % pass.Length]) % kLen;
                byte temp = mBox[i];
                mBox[i] = mBox[j];
                mBox[j] = temp;
            }
            return mBox;
        }
    }
}